﻿using System;
using System.Text.RegularExpressions;
using agsXMPP;
using agsXMPP.protocol.client;
using sharpxbot.Core.Security;
using sharpxbot.Core.Security.Traffic;
using sharpxbot.Core.Security.Traffic.Reports;
using sharpxbot.Plugins.Base;
using sharpxbot.Plugins.Context;
using sharpxbot.Utils.Logging;

namespace sharpxbot.Core.Plugins
{
    /// <summary>
    /// Core-security plugin. Monitors network activity based on socket information and blocks whole
    /// application in the case of exceeding allowed limit
    /// </summary>
    public class TrafficLimiterPlugin : AbstractPlugin
    {
        private static readonly Guid PluginGuid = new Guid("97e31b3e-b843-4760-a729-d1c33567ae78");

        private static readonly Regex commandRegex = new Regex(@"^admin traffic report (?<report_type>daily|hourly)$");

        public override PluginPermissions NeededPermissions
        {
            get { return PluginPermissions.PluginOwner; }
        }

        public override string Name
        {
            get { return "TrafficLimiterPlugin"; }
        }

        public override string Author
        {
            get { return "tillias"; }
        }

        public override Guid GUID
        {
            get { return PluginGuid; }
        }

        public override string Description
        {
            get { return "Network traffic monitor and limiter"; }
        }

        public override string Usage
        {
            get { return "admin traffic report daily[hourly]"; }
        }

        public override void ProcessMessage(Message message)
        {
            if (message == null)
                return;

            if (message.Type == MessageType.chat && message.From.Bare == Context.OwnerJid)
            {
                Match m = commandRegex.Match(message.Body);

                if (m.Success)
                {
                    ITrafficReportGenerator reportGenerator =
                        adminContext.TrafficReportGenerator;

                    ITrafficReport report = null;
                    DateTime now = DateTime.Now;

                    string reportType = m.Groups["report_type"].Value;

                    switch (reportType.ToUpper())
                    {
                        case "DAILY":
                            report = reportGenerator.GetReport(now.Year, now.Month, now.Day);
                            break;
                        case "HOURLY":
                            report = reportGenerator.GetReport(now.Year, now.Month, now.Day, now.Hour);
                            break;
                    }

                    if (report != null)
                    {
                        string reportStr = report.GetText();

                        Message msg = new Message()
                        {
                            To = new Jid(Context.OwnerJid),
                            Type = MessageType.chat,
                            Body = reportStr
                        };

                        Context.Channel.Send(msg);
                    }
                    else
                    {
                        Logger.Write("Can't create traffic report.", LogMessageType.Info);
                    }
                }
            }
        }

        public override void ProcessPresence(Presence presence)
        {
            //no need here
        }

        public TrafficLimiterPlugin(IPluginContext context, IAdminContext adminContext)
            :base(context)
        {
            if (adminContext == null)
                throw new NullReferenceException("Illegal null-reference adminContext. TrafficLimiterPlugin ctor");

            this.adminContext = adminContext;
        }

        #region Private methods

        #endregion

        #region Private fields

        IAdminContext adminContext;

        #endregion
    }
}
